#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
#include <aclapi.h>
#include <bits/stdc++.h>
using namespace std;
#define NTMODEF 1
#define ZWMODEF 0
DWORD ProtectProcess(void){
    HANDLE hProcess = GetCurrentProcess();
    PACL pEmptyDacl;
    DWORD dwErr;

    // using malloc guarantees proper alignment
    pEmptyDacl = (PACL)malloc(sizeof(ACL));

    if (!InitializeAcl(pEmptyDacl, sizeof(ACL), ACL_REVISION)){
        dwErr = GetLastError();
    }
    else{
        dwErr = SetSecurityInfo(hProcess, SE_KERNEL_OBJECT, 
                   DACL_SECURITY_INFORMATION, NULL, NULL, pEmptyDacl, NULL);
    }

    free(pEmptyDacl);
    return dwErr;
}
DWORD ENDVAL=114514;
BOOL MORE;
typedef DWORD (CALLBACK* NTTERMINATEPROCESS)(HANDLE,UINT);
NTTERMINATEPROCESS NtTerminateProcess;
bool NEXT=false;
BOOL SetPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege,BOOL bEnablePrivilege) {
    BOOL bRet = FALSE;
    LUID luid;
    TOKEN_PRIVILEGES tp;

    bRet = LookupPrivilegeValue(NULL,lpszPrivilege,&luid);
    if(!bRet)
        return bRet;
    tp.PrivilegeCount = 1;
    if(bEnablePrivilege)
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    else
        tp.Privileges[0].Attributes = NULL;
    bRet = AdjustTokenPrivileges(hToken,
                                 FALSE,
                                 &tp,
                                 sizeof(TOKEN_PRIVILEGES),
                                 (PTOKEN_PRIVILEGES)NULL,
                                 (PDWORD)NULL);
    if(!bRet)
        return bRet;
    return TRUE;
}
BOOL KillProcess(DWORD PID) {
    HANDLE hProcess = NULL;
    HANDLE hToken        = NULL;
    BOOL        bKilled = FALSE;
    BOOL        bRet        = FALSE;
    bRet = OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken);
    if(!bRet)
        return bRet;
    bRet = SetPrivilege(hToken,SE_DEBUG_NAME,TRUE);
    if(!bRet)
        return bRet;
    hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,PID);
    if(!hProcess)
        return bRet;
    bRet = NtTerminateProcess(hProcess,ENDVAL);
    if(!bRet)
        return bRet;
    bKilled = TRUE;
    CloseHandle(hToken);
    CloseHandle(hProcess);
    return bKilled;
}
pair<DWORD,DWORD> killman(const char *ProcessName,bool mode=false) {
//  cout<<ProcessName<<endl;
    HANDLE hProcess=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    HANDLE hModule;
    PROCESSENTRY32 pinfo;
    MODULEENTRY32 minfo;
    char shortpath[256];DWORD ret=0,cnt=0;
    pinfo.dwSize = sizeof( PROCESSENTRY32 );
    BOOL report =Process32First(hProcess,&pinfo);
    while(report) {
        hModule=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pinfo.th32ProcessID);
        Module32First(hModule, &minfo);
        GetShortPathName(minfo.szExePath,shortpath,256);
//        cout<<"CMP "<<pinfo.szExeFile<<" <> "<<ProcessName<<endl;
        if(!(strcmp(pinfo.szExeFile,ProcessName))) {
        	cnt++;
            if(mode){
            	if(MORE) printf(" 进程ID:%d[属于%d的子进程]\n",pinfo.th32ProcessID,pinfo.th32ParentProcessID);
				goto qq;
			}
            if(!NEXT) hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pinfo.th32ProcessID );
            else OpenProcess( PROCESS_ALL_ACCESS, FALSE, pinfo.th32ProcessID );
			//NtTerminateProcess(hProcess,NULL);
            
            
			BOOL rett=KillProcess(pinfo.th32ProcessID);
            ret+=!rett;
            if(MORE){
            	printf(" 进程ID:%d[属于%d的子进程]:%s\n",pinfo.th32ProcessID,pinfo.th32ParentProcessID,(rett==false?"成功":"拒绝访问"));
			}
//            if(NEXT) hProcess=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,pinfo.th32ProcessID);
        }
qq:
        // AfxMessageBox(pinfo.szExeFile);
    	report =Process32Next(hProcess, &pinfo);
    }
    return make_pair(cnt,ret);
}
void GetSystem() {
    HANDLE hToken;
    LUID sedebugnameValue;
    TOKEN_PRIVILEGES tkp;
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
    LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue);
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = sedebugnameValue;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, false, &tkp, sizeof tkp, NULL, NULL);
    CloseHandle(hToken);
}
void killmain(){
    killman("wscript.exe");
    killman("cmd.exe");
    killman("wscript.exe");
    killman("cmd.exe");
    killman("wscript.exe");
    killman("cmd.exe");
    killman("wscript.exe");
    killman("cmd.exe");
    killman("wscript.exe");
    killman("cmd.exe");
    killman("wscript.exe");
    killman("cmd.exe");
    killman("warning.exe");
    system("sc stop TDFileFilter");
    system("sc stop TDNetFilter");
    killman("GATESRV.exe");
    killman("StudentMain.exe");
    killman("MasterHelper.exe");
    killman("ProcHelper64.exe");
    killman("DispcapHelper.exe");
    killman("InstHelpApp.exe");
    killman("InstHelpApp64.exe");
    return;
}
bool MODE=NTMODEF;bool INPROCREAD=false;
NTTERMINATEPROCESS ZWMODE,NTMODE; 
void cl(string cmd){
	
		if(cmd=="exec"){
			string ch;
			getline(cin,ch,'\n');
			system(ch.c_str());
		}else if(cmd=="killmain") killmain();
		else if(cmd=="switch"){
			cin>>cmd;
			if(cmd=="Zw"){
				NtTerminateProcess = ZWMODE;MODE=ZWMODEF;
				printf("切换为Zw(驱动)模式\n");	
			}else if(cmd=="Nt"){
				NtTerminateProcess = NTMODE;MODE=NTMODEF;
				printf("切换为Nt(内核)模式\n");	
			}
			else if(cmd=="ALL"){
				NEXT=1;
				printf("切换为ALL(所有)模式\n");	
			}else if(cmd=="ONCE"){
				NEXT=0;
				printf("切换为ONCE(仅一次)模式\n");	
			}	
			else if(cmd=="MORE"){
				MORE=1;
				printf("切换为MORE(详细)模式\n");	
			}
			else if(cmd=="LESS"){
				MORE=0;printf("切换为LESS(简略)模式\n");	
			}
			else cout<<"失败:未知开关\n";
		}
		else if(cmd=="exitcode"){
			cin>>ENDVAL;
			printf("返回代码现在已经切换为%d\n",ENDVAL);
		}
		else if(cmd=="cmd"){
			cin>>cmd;
			system(cmd.c_str());
		}
		else if(cmd=="exit"){
			exit(ENDVAL);
		}
		else if(cmd=="help"){
			printf("1.<exename> 以当前配置关闭此exe\n2.switch ALL/ONCE 一个/全部模式\n3.switch Nt/Zw 内核/驱动模式\n4.killmain Kill Mythware\n5.settings 查看配置\n6.exitcode <exitcode> 设置进程结束返回值\n7.exit 退出\n8.help 显示此信息\n9.switch MORE/LESS 更多/简略\n10.exec <command> 运行cmd命令\n11.find <exename> 寻找进程\n12.logo 显示版本信息\n13.kill <exename> 与1相似,唯一的不同是这条命令会将后面一排都理解为exename\n14.read <script> 阅读一个脚本,你也可以在运行参数中指定脚本文件\n15.protect 保护进程不被其他进程关闭\n");
		}
		else if(cmd=="settings"){
			printf("当前使用%s模式,并且会%s。输出%s\n",(MODE?"内核":"驱动"),(NEXT?"终止所有同名进程 ":"只终止最先打开的"),(MORE?"详细":"简略"));
		}
		else if(cmd=="kill"){
			getline(cin,cmd,'\n');
			if(cmd[0]==' ') cmd.erase(cmd.begin());
			pair<DWORD,DWORD> ret=killman(cmd.c_str());
			if(ret.first>0) printf("成功:共%d个进程,终止了%d个进程(失败%d个)\n",ret.first,ret.second,ret.first-ret.second);
			else printf("失败:没有找到进程\n");
		}
		else if(cmd=="logo"){
			printf("NtKiller v3.3 - Command Line Version [hzx 2022]\n");
		}
		else if(cmd=="find"){
			getline(cin,cmd,'\n');
			if(cmd[0]==' ') cmd.erase(cmd.begin());
			pair<DWORD,DWORD> ret=killman(cmd.c_str(),true);
			if(ret.first>0) printf("成功:共%d个进程\n",ret.first);
			else printf("失败:没有找到进程\n");
		}
		else if(cmd=="read"){
			
			INPROCREAD=true;
			string qq;
			cin>>qq;
			printf("正在运行%s:\n",qq.c_str()); 
			fclose(stdin);
			FILE *tmp=freopen(qq.c_str(),"r",stdin);
			if(tmp==NULL){
				printf("错误:文件不存在或者无权访问\n");
				fclose(stdin);
				freopen("CON","r",stdin);
				fflush(stdin);cin.clear();
				
			}
		}
		else if(cmd=="protect"){
			ProtectProcess();
			printf("已运行进程保护\n");
		}
		else{
			pair<DWORD,DWORD> ret=killman(cmd.c_str());
			if(ret.first>0) printf("成功:共%d个进程,终止了%d个进程(失败%d个)\n",ret.first,ret.second,ret.first-ret.second);
			else printf("失败:没有找到进程\n");
		}
}
int main(int argc,char **argv) {
	
    GetSystem();
    HMODULE hNtdll = NULL;
    hNtdll = LoadLibrary( "ntdll.dll" );

    //ntdll.dll?
    if ( !hNtdll ) {
        printf( "在加载ntdll.dll时出现故障\n故障代码:%d\n", GetLastError() );
        system("pause");
        return -1;
    }
    
	ZWMODE=(NTTERMINATEPROCESS) GetProcAddress( hNtdll, "ZwTerminateProcess");
	NTMODE= (NTTERMINATEPROCESS) GetProcAddress( hNtdll, "NtTerminateProcess");
	NtTerminateProcess = NTMODE;
	if(NtTerminateProcess==NULL||ZWMODE==NULL){
		printf( "在加载ntdll.dll/NtTerminateProcess时出现故障\n故障代码:%d\n", GetLastError() );
        system("pause");
        return -1;
	}
	if(argc>1){
		SetWindowPos(GetConsoleWindow(),HWND_NOTOPMOST,0,0,0,0,SWP_HIDEWINDOW);
		if(freopen(argv[1],"r",stdin)==NULL){
			printf("失败:不存在的文件\n");
			return ENDVAL;
		}
//		return 0;
	}
	
	cin.tie(0);cout.tie(0);
	printf("NtKiller Shell. - Command Line. hzx 2022\n");
	while(true){
		printf(">>>");
		if(feof(stdin)){
			if(!INPROCREAD) return 0;
			else{
				printf("完成...\n");
				INPROCREAD=false;
				fclose(stdin);
//				stdin=fopen("CON","r");
				freopen("CON","r",stdin);
				fflush(stdin);fflush(stdout);
//				continue;
				cin.clear();
				continue;
			}
		}
		
		string cmd;
		cin>>cmd;
		cl(cmd); 
	}
    return 0;
}